ํ๋ก ํธ์๋ ์ฑ๋ฅ API์ Resource Observer๋ก ๋ฆฌ์์ค ๋ก๋ ๋ชจ๋ํฐ๋ง์ ๋ง์คํฐํ์ธ์. ์น์ฌ์ดํธ ๋ก๋ฉ ์๊ฐ์ ์ต์ ํํ๊ณ , ์ฑ๋ฅ ๋ณ๋ชฉ ํ์์ ์๋ณํ๋ฉฐ, ์ฐ์ํ ์ฌ์ฉ์ ๊ฒฝํ์ ์ ๊ณตํฉ๋๋ค.
ํ๋ก ํธ์๋ ์ฑ๋ฅ API: ๋ก๋ ๋ชจ๋ํฐ๋ง์ ์ํ Resource Observer
์ค๋๋ ์ ๋์งํธ ํ๊ฒฝ์์ ์น์ฌ์ดํธ ์ฑ๋ฅ์ ๋งค์ฐ ์ค์ํฉ๋๋ค. ์ฌ์ฉ์๋ค์ ๋น ๋ฅธ ๋ก๋ฉ ์๊ฐ๊ณผ ์ํํ ๊ฒฝํ์ ๊ธฐ๋ํฉ๋๋ค. ๋๋ฆฐ ๋ก๋ฉ ์๊ฐ์ ๋์ ์ดํ๋ฅ , ์ฐธ์ฌ๋ ๊ฐ์, ๊ทธ๋ฆฌ๊ณ ๊ถ๊ทน์ ์ผ๋ก๋ ์์ต ์์ค๋ก ์ด์ด์ง ์ ์์ต๋๋ค. ์น์ฌ์ดํธ์ ์ฑ๋ฅ์ ์ต์ ํํ๋ ค๋ฉด ๋ธ๋ผ์ฐ์ ๊ฐ ๋ฆฌ์์ค๋ฅผ ์ด๋ป๊ฒ ๋ก๋ํ๊ณ ์ฒ๋ฆฌํ๋์ง์ ๋ํ ๊น์ ์ดํด๊ฐ ํ์ํฉ๋๋ค. ๋ฐ๋ก ์ด ์ง์ ์์ ํ๋ก ํธ์๋ ์ฑ๋ฅ API, ํนํ Resource Observer๊ฐ ์ค์ํ ์ญํ ์ ํฉ๋๋ค.
๋ฆฌ์์ค ๋ก๋ ๋ชจ๋ํฐ๋ง์ ์ค์์ฑ ์ดํดํ๊ธฐ
๋ฆฌ์์ค ๋ก๋ ๋ชจ๋ํฐ๋ง์ ์ด๋ฏธ์ง, ์คํฌ๋ฆฝํธ, ์คํ์ผ์ํธ, ํฐํธ์ ๊ฐ์ ์นํ์ด์ง์ ๋ค์ํ ๋ฆฌ์์ค ๋ก๋ฉ ๋ฐ ์ฒ๋ฆฌ๋ฅผ ์ถ์ ํ๋ ๊ฒ์ ํฌํจํฉ๋๋ค. ์ด๋ฌํ ๋ฆฌ์์ค๋ฅผ ๋ชจ๋ํฐ๋งํจ์ผ๋ก์จ ๊ฐ๋ฐ์๋ ๋ณ๋ชฉ ํ์์ ์๋ณํ๊ณ , ๋ฆฌ์์ค ์ ๋ฌ์ ์ต์ ํํ๋ฉฐ, ์ ๋ฐ์ ์ธ ์น์ฌ์ดํธ ์ฑ๋ฅ์ ํฅ์์ํฌ ์ ์์ต๋๋ค. Resource Observer๋ ์ด๋ฅผ ๋ฌ์ฑํ๊ธฐ ์ํ ๊ฐ๋ ฅํ ๋ฉ์ปค๋์ฆ์ ์ ๊ณตํฉ๋๋ค.
์ฑ๋ฅ ๋ชจ๋ํฐ๋ง์ด ์ค์ํ ์ด์
- ์ฌ์ฉ์ ๊ฒฝํ ํฅ์: ๋ ๋น ๋ฅธ ๋ก๋ฉ ์๊ฐ์ ๋ ์ฆ๊ฒ๊ณ ๋งค๋ ฅ์ ์ธ ์ฌ์ฉ์ ๊ฒฝํ์ผ๋ก ์ด์ด์ง๋๋ค.
- ์ดํ๋ฅ ๊ฐ์: ์น์ฌ์ดํธ๊ฐ ๋น ๋ฅด๊ฒ ๋ก๋๋๋ฉด ์ฌ์ฉ์๊ฐ ์ดํํ ๊ฐ๋ฅ์ฑ์ด ์ค์ด๋ญ๋๋ค.
- SEO ๊ฐํ: ๊ตฌ๊ธ๊ณผ ๊ฐ์ ๊ฒ์ ์์ง์ ์น์ฌ์ดํธ ์ฑ๋ฅ์ ์์ ๊ฒฐ์ ์์ธ์ผ๋ก ๊ณ ๋ คํฉ๋๋ค.
- ์ ํ์จ ์ฆ๊ฐ: ๋ ๋น ๋ฅธ ์น์ฌ์ดํธ๋ ์ข ์ข ๋ ๋์ ์ ํ์จ์ ๋ณด์ ๋๋ค.
- ์ธํ๋ผ ๋น์ฉ ์ ๊ฐ: ๋ฆฌ์์ค ์ ๋ฌ์ ์ต์ ํํ๋ฉด ๋์ญํญ ์๋น์ ์๋ฒ ๋ถํ๋ฅผ ์ค์ผ ์ ์์ต๋๋ค.
ํ๋ก ํธ์๋ ์ฑ๋ฅ API ์๊ฐ
ํ๋ก ํธ์๋ ์ฑ๋ฅ API๋ ๋ธ๋ผ์ฐ์ ์์ ์ฑ๋ฅ ๊ด๋ จ ๋ฐ์ดํฐ์ ์ ๊ทผํ ์ ์๋๋ก ํ๋ ์ธํฐํ์ด์ค์ ๊ฐ์ฒด๋ค์ ๋ชจ์์ ๋๋ค. ์ด API๋ฅผ ํตํด ๊ฐ๋ฐ์๋ ๋ค์๊ณผ ๊ฐ์ ์น์ฌ์ดํธ ์ฑ๋ฅ์ ๋ค์ํ ์ธก๋ฉด์ ์ธก์ ํ๊ณ ๋ถ์ํ ์ ์์ต๋๋ค:
- Navigation Timing: ์นํ์ด์ง๋ฅผ ๋ก๋ํ๋ ๋ฐ ๊ฑธ๋ฆฌ๋ ์๊ฐ์ ์ธก์ ํฉ๋๋ค.
- Resource Timing: ๊ฐ๋ณ ๋ฆฌ์์ค๋ฅผ ๋ก๋ํ๋ ๋ฐ ๊ฑธ๋ฆฌ๋ ์๊ฐ์ ์ธก์ ํฉ๋๋ค.
- User Timing: ๊ฐ๋ฐ์๊ฐ ์ฌ์ฉ์ ์ง์ ์ฑ๋ฅ ์งํ๋ฅผ ์ ์ํ ์ ์๋๋ก ํฉ๋๋ค.
- Long Tasks API: ๋ฉ์ธ ์ค๋ ๋๋ฅผ ์ฐจ๋จํ๋ ์ค๋ ์คํ๋๋ ์์ ์ ์๋ณํฉ๋๋ค.
- Largest Contentful Paint (LCP): ํ์ด์ง์์ ๊ฐ์ฅ ํฐ ์ฝํ ์ธ ์์๋ฅผ ๋ ๋๋งํ๋ ๋ฐ ๊ฑธ๋ฆฌ๋ ์๊ฐ์ ์ธก์ ํฉ๋๋ค.
- First Input Delay (FID): ๋ธ๋ผ์ฐ์ ๊ฐ ์ฒซ ๋ฒ์งธ ์ฌ์ฉ์ ์ํธ์์ฉ์ ์๋ตํ๋ ๋ฐ ๊ฑธ๋ฆฌ๋ ์๊ฐ์ ์ธก์ ํฉ๋๋ค.
- Cumulative Layout Shift (CLS): ํ์ด์ง์ ์๊ฐ์ ์์ ์ฑ์ ์ธก์ ํฉ๋๋ค.
Resource Observer๋ ํ๋ก ํธ์๋ ์ฑ๋ฅ API์ ์ผ๋ถ์ด๋ฉฐ ๊ฐ๋ณ ๋ฆฌ์์ค์ ๋ก๋ฉ์ ๋ํ ๋ฐ์ดํฐ๋ฅผ ๊ด์ฐฐํ๊ณ ์์งํ๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค.
Resource Observer: ์ฌ์ธต ๋ถ์
Resource Observer๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฆฌ์์ค ํ์ด๋ฐ ํญ๋ชฉ์ด ์์ฑ๋ ๋ ์๋ฆผ์ ์ ๊ณตํ์ฌ ์นํ์ด์ง์ ๋ฆฌ์์ค ๋ก๋ฉ์ ๋ชจ๋ํฐ๋งํ ์ ์์ต๋๋ค. ์ด๋ฅผ ํตํด ๊ฐ๋ณ ๋ฆฌ์์ค์ ์ฑ๋ฅ์ ์ถ์ ํ๊ณ ์ ์ฌ์ ์ธ ๋ณ๋ชฉ ํ์์ ์๋ณํ ์ ์์ต๋๋ค.
Resource Observer ์๋ ๋ฐฉ์
Resource Observer๋ PerformanceObserver๋ฅผ ๊ด์ฐฐํ๊ณ ํน์ ์ฑ๋ฅ ํญ๋ชฉ ์ ํ, ํนํ `resource` ํญ๋ชฉ์ ์์ ํ์ฌ ์๋ํฉ๋๋ค. ๊ฐ `resource` ํญ๋ชฉ์๋ ๋ค์๊ณผ ๊ฐ์ ํน์ ๋ฆฌ์์ค์ ๋ก๋ฉ์ ๋ํ ์์ธํ ์ ๋ณด๊ฐ ํฌํจ๋ฉ๋๋ค:
- name: ๋ฆฌ์์ค์ URL์ ๋๋ค.
- entryType: ์ฑ๋ฅ ํญ๋ชฉ์ ์ ํ์ ๋๋ค (์ด ๊ฒฝ์ฐ, `resource`).
- startTime: ๋ฆฌ์์ค ๋ก๋ฉ์ด ์์๋ ์๊ฐ์ ๋๋ค.
- duration: ๋ฆฌ์์ค๋ฅผ ๋ก๋ํ๋ ๋ฐ ๊ฑธ๋ฆฐ ์ด ์๊ฐ์ ๋๋ค.
- initiatorType: ๋ฆฌ์์ค ์์ฒญ์ ์์ํ ์์์ ์ ํ์ ๋๋ค (์: `img`, `script`, `link`).
- transferSize: ๋คํธ์ํฌ๋ฅผ ํตํด ์ ์ก๋ ๋ฆฌ์์ค์ ํฌ๊ธฐ์ ๋๋ค.
- encodedBodySize: ์์ถ ์ ๋ฆฌ์์ค์ ํฌ๊ธฐ์ ๋๋ค.
- decodedBodySize: ์์ถ ํด์ ํ ๋ฆฌ์์ค์ ํฌ๊ธฐ์ ๋๋ค.
- connectStart: ๋ธ๋ผ์ฐ์ ๊ฐ ๋ฆฌ์์ค๋ฅผ ๊ฒ์ํ๊ธฐ ์ํด ์๋ฒ์ ๋ํ ์ฐ๊ฒฐ ์ค์ ์ ์์ํ๊ธฐ ์ง์ ์ ์๊ฐ์ ๋๋ค.
- connectEnd: ๋ธ๋ผ์ฐ์ ๊ฐ ๋ฆฌ์์ค๋ฅผ ๊ฒ์ํ๊ธฐ ์ํด ์๋ฒ์ ๋ํ ์ฐ๊ฒฐ ์ค์ ์ ์๋ฃํ ์งํ์ ์๊ฐ์ ๋๋ค.
- domainLookupStart: ๋ธ๋ผ์ฐ์ ๊ฐ ๋ฆฌ์์ค์ ๋ํ ๋๋ฉ์ธ ์ด๋ฆ ์กฐํ๋ฅผ ์์ํ๊ธฐ ์ง์ ์ ์๊ฐ์ ๋๋ค.
- domainLookupEnd: ๋ธ๋ผ์ฐ์ ๊ฐ ๋ฆฌ์์ค์ ๋ํ ๋๋ฉ์ธ ์ด๋ฆ ์กฐํ๋ฅผ ์๋ฃํ ์งํ์ ์๊ฐ์ ๋๋ค.
- fetchStart: ๋ธ๋ผ์ฐ์ ๊ฐ ๋ฆฌ์์ค ๊ฐ์ ธ์ค๊ธฐ๋ฅผ ์์ํ๊ธฐ ์ง์ ์ ์๊ฐ์ ๋๋ค.
- responseStart: ๋ธ๋ผ์ฐ์ ๊ฐ ์๋ต์ ์ฒซ ๋ฐ์ดํธ๋ฅผ ์์ ํ ์งํ์ ์๊ฐ์ ๋๋ค.
- responseEnd: ๋ธ๋ผ์ฐ์ ๊ฐ ์๋ต์ ๋ง์ง๋ง ๋ฐ์ดํธ๋ฅผ ์์ ํ ์งํ์ ์๊ฐ์ ๋๋ค.
- secureConnectionStart: ๋ธ๋ผ์ฐ์ ๊ฐ ํ์ฌ ์ฐ๊ฒฐ์ ๋ณด์ํ๊ธฐ ์ํด ํธ๋์ ฐ์ดํฌ ํ๋ก์ธ์ค๋ฅผ ์์ํ๊ธฐ ์ง์ ์ ์๊ฐ์ ๋๋ค.
- requestStart: ๋ธ๋ผ์ฐ์ ๊ฐ ์๋ฒ, ์บ์ ๋๋ ๋ก์ปฌ ๋ฆฌ์์ค์์ ๋ฆฌ์์ค ์์ฒญ์ ์์ํ๊ธฐ ์ง์ ์ ์๊ฐ์ ๋๋ค.
Resource Observer ์์ฑํ๊ธฐ
Resource Observer๋ฅผ ์์ฑํ๋ ค๋ฉด `PerformanceObserver` ์์ฑ์๋ฅผ ์ฌ์ฉํ๊ณ `entryTypes` ์ต์ ์ ์ง์ ํด์ผ ํฉ๋๋ค:
const observer = new PerformanceObserver((list) => {
list.getEntries().forEach((entry) => {
// Process the resource entry
console.log(entry);
});
});
observer.observe({ entryTypes: ['resource'] });
์ด ์ฝ๋๋ `resource` ํญ๋ชฉ์ ์์ ํ๋ ์๋ก์ด `PerformanceObserver`๋ฅผ ์์ฑํฉ๋๋ค. ์๋ก์ด ๋ฆฌ์์ค ํญ๋ชฉ์ด ์์ฑ๋๋ฉด ์ฝ๋ฐฑ ํจ์๊ฐ ์คํ๋๊ณ , `entry` ๊ฐ์ฒด์๋ ๋ฆฌ์์ค์ ๋ํ ์์ธํ ์ ๋ณด๊ฐ ํฌํจ๋ฉ๋๋ค.
๋ฆฌ์์ค ํ์ด๋ฐ ๋ฐ์ดํฐ ๋ถ์ํ๊ธฐ
๋ฆฌ์์ค ํ์ด๋ฐ ๋ฐ์ดํฐ๋ฅผ ํ๋ณดํ๋ฉด ์ด๋ฅผ ๋ถ์ํ์ฌ ์ฑ๋ฅ ๋ณ๋ชฉ ํ์์ ์๋ณํ ์ ์์ต๋๋ค. ๋ค์์ ์กฐ์ฌํ ์ผ๋ฐ์ ์ธ ์์ญ์ ๋๋ค:
- ๊ธด ๋ก๋ฉ ์๊ฐ: ๋ก๋ํ๋ ๋ฐ ์๊ฐ์ด ์ค๋ ๊ฑธ๋ฆฌ๋ ๋ฆฌ์์ค๋ฅผ ์๋ณํ๊ณ ๊ทธ ์์ธ์ ์กฐ์ฌํฉ๋๋ค. ์ด๋ ํฐ ํ์ผ ํฌ๊ธฐ, ๋๋ฆฐ ์๋ฒ ๋๋ ๋คํธ์ํฌ ๋ฌธ์ ๋๋ฌธ์ผ ์ ์์ต๋๋ค.
- ํฐ ์ ์ก ํฌ๊ธฐ: ์ ์ก ํฌ๊ธฐ๊ฐ ํฐ ๋ฆฌ์์ค๋ฅผ ์๋ณํ๊ณ ์ด๋ฏธ์ง ์์ถ, ์ฝ๋ ์ถ์ ๋๋ ์ฝ๋ ๋ถํ ์ ์ฌ์ฉํ์ฌ ์ต์ ํํ๋ ๊ฒ์ ๊ณ ๋ คํฉ๋๋ค.
- ๋๋ฆฐ ์ฐ๊ฒฐ ์๊ฐ: ์ฐ๊ฒฐ ์๊ฐ์ด ๋๋ฆฐ ๋ฆฌ์์ค๋ฅผ ์กฐ์ฌํ๊ณ CDN์ ์ฌ์ฉํ๊ฑฐ๋ ์๋ฒ ๊ตฌ์ฑ์ ์ต์ ํํ๋ ๊ฒ์ ๊ณ ๋ คํฉ๋๋ค.
- DNS ์กฐํ ์๊ฐ: DNS ์กฐํ ์๊ฐ์ด ๋๋ฆฐ ๋ฆฌ์์ค๋ฅผ ์กฐ์ฌํ๊ณ DNS ํ๋ฆฌํ์นญ์ ์ฌ์ฉํ๋ ๊ฒ์ ๊ณ ๋ คํฉ๋๋ค.
Resource Observer ์ฌ์ฉ์ ์ค์ ์์
๋ค์์ Resource Observer๋ฅผ ์ฌ์ฉํ์ฌ ๋ฆฌ์์ค ๋ก๋ฉ์ ๋ชจ๋ํฐ๋งํ๊ณ ์ต์ ํํ๋ ๋ฐฉ๋ฒ์ ๋ํ ๋ช ๊ฐ์ง ์ค์ ์์ ์ ๋๋ค:
์์ 1: ์ฉ๋์ด ํฐ ์ด๋ฏธ์ง ์๋ณํ๊ธฐ
์ด ์์ ๋ Resource Observer๋ฅผ ์ฌ์ฉํ์ฌ ์ง์ ๋ ํฌ๊ธฐ๋ณด๋ค ํฐ ์ด๋ฏธ์ง๋ฅผ ์๋ณํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค๋๋ค:
const observer = new PerformanceObserver((list) => {
list.getEntries().forEach((entry) => {
if (entry.initiatorType === 'img' && entry.transferSize > 100000) { // 100KB
console.warn(`Large image detected: ${entry.name} (${entry.transferSize} bytes)`);
}
});
});
observer.observe({ entryTypes: ['resource'] });
์ด ์ฝ๋๋ 100KB๋ณด๋ค ํฐ ๋ชจ๋ ์ด๋ฏธ์ง์ ๋ํด ์ฝ์์ ๊ฒฝ๊ณ ๋ฉ์์ง๋ฅผ ๊ธฐ๋กํฉ๋๋ค.
์์ 2: ์คํฌ๋ฆฝํธ ๋ก๋ฉ ์๊ฐ ๋ชจ๋ํฐ๋งํ๊ธฐ
์ด ์์ ๋ Resource Observer๋ฅผ ์ฌ์ฉํ์ฌ ์๋ฐ์คํฌ๋ฆฝํธ ํ์ผ์ ๋ก๋ฉ ์๊ฐ์ ๋ชจ๋ํฐ๋งํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค๋๋ค:
const observer = new PerformanceObserver((list) => {
list.getEntries().forEach((entry) => {
if (entry.initiatorType === 'script') {
console.log(`Script loaded: ${entry.name} in ${entry.duration} ms`);
}
});
});
observer.observe({ entryTypes: ['resource'] });
์ด ์ฝ๋๋ ๊ฐ ์คํฌ๋ฆฝํธ ํ์ผ์ URL๊ณผ ๋ก๋ฉ ์๊ฐ์ ์ฝ์์ ๊ธฐ๋กํฉ๋๋ค.
์์ 3: ํฐํธ ๋ก๋ฉ ์ถ์ ํ๊ธฐ
ํฐํธ๋ ์ข ์ข ์ฑ๋ฅ ๋ณ๋ชฉ ํ์์ ์์ธ์ด ๋ ์ ์์ต๋๋ค. ์ด ์์ ๋ ํฐํธ ๋ก๋ฉ ์๊ฐ์ ๋ชจ๋ํฐ๋งํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค๋๋ค:
const observer = new PerformanceObserver((list) => {
list.getEntries().forEach((entry) => {
if (entry.initiatorType === 'link' && entry.name.endsWith('.woff2')) { // Assuming WOFF2 fonts
console.log(`Font loaded: ${entry.name} in ${entry.duration} ms`);
}
});
});
observer.observe({ entryTypes: ['resource'] });
์ด ์ฝ๋๋ ๋ชจ๋ WOFF2 ํฐํธ ํ์ผ์ URL๊ณผ ๋ก๋ฉ ์๊ฐ์ ์ฝ์์ ๊ธฐ๋กํฉ๋๋ค.
์์ 4: ์๋ํํฐ ๋ฆฌ์์ค ๋ณ๋ชฉ ํ์ ์๋ณํ๊ธฐ
์ข ์ข ์ฑ๋ฅ ๋ฌธ์ ๋ ์๋ํํฐ ์คํฌ๋ฆฝํธ ๋ฐ ๋ฆฌ์์ค์์ ๋น๋กฏ๋ฉ๋๋ค. ์ด ์์ ๋ ์ด๋ฅผ ์๋ณํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค๋๋ค:
const observer = new PerformanceObserver((list) => {
list.getEntries().forEach((entry) => {
if (entry.name.includes('example.com')) { // Replace with the third-party domain
console.warn(`Third-party resource: ${entry.name} took ${entry.duration} ms to load`);
}
});
});
observer.observe({ entryTypes: ['resource'] });
์ด ์ฝ๋๋ ์ง์ ๋ ์๋ํํฐ ๋๋ฉ์ธ์์ ๋ก๋๋ ๋ชจ๋ ๋ฆฌ์์ค์ ๋ํด ๋ก๋ฉ ์๊ฐ๊ณผ ํจ๊ป ์ฝ์์ ๊ฒฝ๊ณ ๋ฉ์์ง๋ฅผ ๊ธฐ๋กํฉ๋๋ค.
Resource Observer ์ฌ์ฉ์ ์ํ ๋ชจ๋ฒ ์ฌ๋ก
Resource Observer๋ฅผ ํจ๊ณผ์ ์ผ๋ก ์ฌ์ฉํ๋ ค๋ฉด ๋ค์ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ๋ฐ๋ฅด์ญ์์ค:
- ์กฐ๊ธฐ ์์: ๊ฐ๋ฐ ํ๋ก์ธ์ค์ ๊ฐ๋ฅํ ํ ์ด๋ฅธ ๋จ๊ณ์์ ๋ฆฌ์์ค ๋ชจ๋ํฐ๋ง์ ๊ตฌํํฉ๋๋ค.
- ์ ๊ธฐ์ ๋ชจ๋ํฐ๋ง: ์ฑ๋ฅ ๋ฌธ์ ๋ฅผ ์๋ณํ๊ณ ํด๊ฒฐํ๊ธฐ ์ํด ๋ฆฌ์์ค ๋ก๋ฉ์ ์ง์์ ์ผ๋ก ๋ชจ๋ํฐ๋งํฉ๋๋ค.
- ์ฑ๋ฅ ์์ฐ ์ค์ : ๋ค์ํ ๋ฆฌ์์ค ์ ํ์ ๋ํ ์ฑ๋ฅ ์์ฐ์ ์ ์ํ๊ณ ์ด ์์ฐ์ ๋ํ ์งํ ์ํฉ์ ์ถ์ ํฉ๋๋ค.
- ์ค์ ๋ฐ์ดํฐ ์ฌ์ฉ: ์ค์ ์ฌ์ฉ์๋ก๋ถํฐ ๋ฆฌ์์ค ํ์ด๋ฐ ๋ฐ์ดํฐ๋ฅผ ์์งํ์ฌ ์น์ฌ์ดํธ ์ฑ๋ฅ์ ๋ํ ๋ ์ ํํ ๊ทธ๋ฆผ์ ์ป์ต๋๋ค.
- ๋ชจ๋ํฐ๋ง ๋๊ตฌ์ ํตํฉ: ๋ฐ์ดํฐ ์์ง ๋ฐ ๋ถ์์ ์๋ํํ๊ธฐ ์ํด Resource Observer๋ฅผ ๋ชจ๋ํฐ๋ง ๋๊ตฌ์ ํตํฉํฉ๋๋ค.
- ๋ค์ํ ๊ธฐ๊ธฐ ๋ฐ ๋คํธ์ํฌ์ ๋ํ ์ต์ ํ: ๋ฆฌ์์ค ๋ก๋ฉ ์ฑ๋ฅ์ด ๋ค์ํ ๊ธฐ๊ธฐ ๋ฐ ๋คํธ์ํฌ์์ ์ด๋ป๊ฒ ๋ค๋ฅธ์ง ๊ณ ๋ คํ๊ณ ๊ทธ์ ๋ฐ๋ผ ์ต์ ํํฉ๋๋ค.
๊ณ ๊ธ ๊ธฐ์ ๋ฐ ๊ณ ๋ ค ์ฌํญ
๋ฒํผ๋ง๊ณผ `buffered` ์์ฑ
`PerformanceObserver`๋ ์ฑ๋ฅ ํญ๋ชฉ์ ๋ฒํผ๋ง์ ์ง์ํฉ๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก ํญ๋ชฉ์ ๋ฐ์ํ ๋ ์ ๋ฌ๋ฉ๋๋ค. ๊ทธ๋ฌ๋ `buffered` ์์ฑ์ ์ฌ์ฉํ์ฌ ์ต์ ๋ฒ๊ฐ ํญ๋ชฉ์ ์ผ๊ด์ ์ผ๋ก ์ ๋ฌํ๋๋ก ๊ตฌ์ฑํ ์ ์์ต๋๋ค:
const observer = new PerformanceObserver((list) => {
list.getEntries().forEach((entry) => {
console.log(entry);
});
}, { entryTypes: ['resource'], buffered: true });
observer.observe({ entryTypes: ['resource'] });
`buffered`๋ฅผ `true`๋ก ์ค์ ํ๋ฉด ์ต์ ๋ฒ๊ฐ ์์ฑ๋ ๋ ๊ธฐ์กด์ ๋ชจ๋ ํญ๋ชฉ์ด ์ ๋ฌ๋๋ฏ๋ก ๊ณผ๊ฑฐ ๋ฐ์ดํฐ๋ฅผ ์์งํ๋ ๋ฐ ์ ์ฉํ ์ ์์ต๋๋ค.
`clear()`์ `disconnect()` ์ฌ์ฉํ๊ธฐ
์ฑ๋ฅ ํญ๋ชฉ ๊ด์ฐฐ์ ์ค์งํ๋ ค๋ฉด `disconnect()` ๋ฉ์๋๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค:
observer.disconnect();
์ด๋ ๊ฒ ํ๋ฉด ์ต์ ๋ฒ๊ฐ ์๋ก์ด ์ฑ๋ฅ ํญ๋ชฉ์ ์์ ํ๋ ๊ฒ์ ์ค์งํฉ๋๋ค. `clear()` ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ๋ฒํผ๋ง๋ ๋ชจ๋ ํญ๋ชฉ์ ์ ๊ฑฐํ ์๋ ์์ต๋๋ค:
observer.clear();
์ค๋ฅ ์ฒ๋ฆฌ
Performance API๋ก ์์ ํ ๋๋ ์ ์ ํ ์ค๋ฅ ์ฒ๋ฆฌ๋ฅผ ๊ตฌํํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. ์ด API๋ ๋ชจ๋ ๋ธ๋ผ์ฐ์ ์์ ์ง์๋์ง ์์ ์ ์์ผ๋ฉฐ, ์๋ชป ์ฌ์ฉ๋ ๊ฒฝ์ฐ ์ค๋ฅ๋ฅผ ๋ฐ์์ํฌ ์ ์์ต๋๋ค. ์ ์ฌ์ ์ธ ์ค๋ฅ๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํด `try...catch` ๋ธ๋ก์ ์ฌ์ฉํ์ญ์์ค:
try {
const observer = new PerformanceObserver((list) => {
list.getEntries().forEach((entry) => {
console.log(entry);
});
});
observer.observe({ entryTypes: ['resource'] });
} catch (error) {
console.error('PerformanceObserver not supported:', error);
}
์ง์ญ๋ณ ์ค์ ์ฌ๋ก
์ด๋ฌํ ๊ธฐ์ ์ด ๋ค์ํ ์ง๋ฆฌ์ ๋งฅ๋ฝ์์ ์ด๋ป๊ฒ ์ ์ฉ๋ ์ ์๋์ง ์ดํด๋ณด๊ฒ ์ต๋๋ค:
- ๋์ญํญ์ด ์ ํ๋ ๊ฐ๋ฐ๋์๊ตญ: ํ๊ท ๋์ญํญ์ด ๋ฎ์ ์ง์ญ์์๋ ๋ฆฌ์์ค ์ต์ ํ๋ฅผ ์ฐ์ ์ํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. ์ฌ๊ธฐ์๋ ์ ๊ทน์ ์ธ ์ด๋ฏธ์ง ์์ถ, ์ฝ๋ ์ถ์ ๋ฐ ํจ์จ์ ์ธ ์บ์ฑ ์ ๋ต์ด ํฌํจ๋ฉ๋๋ค. ์ด๋ฌํ ์ง์ญ์ ์ต์ ํ๋ CDN์ ํ์ฉํ๋ ๊ฒ๋ ์ฑ๋ฅ์ ํฌ๊ฒ ํฅ์์ํฌ ์ ์์ต๋๋ค.
- ๋ชจ๋ฐ์ผ ์ฐ์ ์์ฅ: ๋ชจ๋ฐ์ผ ์ธํฐ๋ท ์ ์์ด ์ง๋ฐฐ์ ์ธ ๊ตญ๊ฐ์์๋ ํ์ด๋ก๋ ํฌ๊ธฐ๋ฅผ ์ค์ด๊ณ ๋ชจ๋ฐ์ผ ์ฅ์น์ ์ต์ ํํ๋ ๋ฐ ์ค์ ์ ๋ก๋๋ค. ์ฌ๊ธฐ์๋ ๋ฐ์ํ ์ด๋ฏธ์ง ์ฌ์ฉ, ์ง์ฐ ๋ก๋ฉ ๋ฐ ์คํ๋ผ์ธ ์บ์ฑ์ ์ํ ์๋น์ค ์์ปค ๊ตฌํ์ด ํฌํจ๋ ์ ์์ต๋๋ค.
- ๋คํธ์ํฌ ์กฐ๊ฑด์ด ๋ค์ํ ์ง์ญ: ๋คํธ์ํฌ ์ฐ๊ฒฐ์ด ๋ถ์์ ํ ์ง์ญ์์๋ ์ฌ์ฉ์์ ์ฐ๊ฒฐ ์๋์ ๋ฐ๋ผ ๋ฆฌ์์ค ์ ๋ฌ์ ์กฐ์ ํ๋ ์ ์ํ ๋ก๋ฉ ์ ๋ต์ ๊ณ ๋ คํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ๋๋ฆฐ ์ฐ๊ฒฐ์์๋ ์ ํด์๋ ์ด๋ฏธ์ง๋ฅผ ์ ๊ณตํ๊ฑฐ๋ ์ ๋๋ฉ์ด์ ์ ๋นํ์ฑํํ ์ ์์ต๋๋ค.
- ์ ์ธ๊ณ์ ๋ฐฐํฌ๋ ์ ํ๋ฆฌ์ผ์ด์ : ์ ์ธ๊ณ ์ฌ์ฉ์๋ฅผ ๋์์ผ๋ก ํ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฒฝ์ฐ, ๊ธ๋ก๋ฒ CDN์ ์ฌ์ฉํ๊ณ ๋ค์ํ ์๊ฐ๋์ ์ธ์ด์ ๋ง๊ฒ ์ต์ ํํ๋ฉด ์ฌ์ฉ์ ๊ฒฝํ์ ํฌ๊ฒ ํฅ์์ํฌ ์ ์์ต๋๋ค.
์๋ฅผ ๋ค์ด, ์ธ๋ ์ฌ์ฉ์๋ฅผ ๋์์ผ๋ก ํ๋ ์ฃผ์ ์ ์์๊ฑฐ๋ ์น์ฌ์ดํธ๋ ๋ฎ์ ํ๊ท ๋์ญํญ๊ณผ ๋์ ๋ชจ๋ฐ์ผ ์ฌ์ฉ๋์ผ๋ก ์ธํด ์ด๋ฏธ์ง ์์ถ ๋ฐ ๋ชจ๋ฐ์ผ ์ต์ ํ๋ฅผ ์ฐ์ ์ํ ์ ์์ต๋๋ค. ์ ๋ฝ ์ฌ์ฉ์๋ฅผ ๋์์ผ๋ก ํ๋ ๋ด์ค ์น์ฌ์ดํธ๋ ์ฌ์ฉ์ ์ฐธ์ฌ๋๋ฅผ ๋์ด๊ธฐ ์ํด GDPR ์ค์ ๋ฐ ๋น ๋ฅธ ๋ก๋ฉ ์๊ฐ์ ์ค์ ์ ๋ ์ ์์ต๋๋ค.
Resource Observer๋ฅผ ๋์ด: ๋ณด์ ๊ธฐ์
Resource Observer๋ ๊ฐ๋ ฅํ ๋๊ตฌ์ด์ง๋ง ๋ค๋ฅธ ์ฑ๋ฅ ์ต์ ํ ๊ธฐ์ ๊ณผ ํจ๊ป ์ฌ์ฉํ ๋ ๊ฐ์ฅ ํจ๊ณผ์ ์ ๋๋ค:
- ์ฝํ ์ธ ์ ์ก ๋คํธ์ํฌ(CDN): CDN์ ์น์ฌ์ดํธ์ ์ฝํ ์ธ ๋ฅผ ์ ์ธ๊ณ ์ฌ๋ฌ ์๋ฒ์ ๋ถ์ฐ์์ผ ์ง์ฐ ์๊ฐ์ ์ค์ด๊ณ ๋ก๋ฉ ์๊ฐ์ ๊ฐ์ ํฉ๋๋ค.
- ์ด๋ฏธ์ง ์ต์ ํ: ์ด๋ฏธ์ง๋ฅผ ์์ถํ๊ณ ํฌ๊ธฐ๋ฅผ ์กฐ์ ํ๋ฉฐ WebP์ ๊ฐ์ ์ต์ ์ด๋ฏธ์ง ํ์์ ์ฌ์ฉํ์ฌ ํ์ผ ํฌ๊ธฐ๋ฅผ ํฌ๊ฒ ์ค์ผ ์ ์์ต๋๋ค.
- ์ฝ๋ ์ถ์ ๋ฐ ๋ฒ๋ค๋ง: ์๋ฐ์คํฌ๋ฆฝํธ ๋ฐ CSS ์ฝ๋๋ฅผ ์ถ์ํ๊ณ ๋ฒ๋ค๋งํ๋ฉด ํ์ผ ํฌ๊ธฐ์ ๋ก๋์ ํ์ํ HTTP ์์ฒญ ์๋ฅผ ์ค์ผ ์ ์์ต๋๋ค.
- ์บ์ฑ: ์บ์ฑ์ ํตํด ๋ธ๋ผ์ฐ์ ๋ ๋ฆฌ์์ค๋ฅผ ๋ก์ปฌ์ ์ ์ฅํ์ฌ ํ์ ๋ฐฉ๋ฌธ ์ ๋ค์ ๋ค์ด๋ก๋ํ ํ์์ฑ์ ์ค์ ๋๋ค.
- ์ง์ฐ ๋ก๋ฉ: ์ง์ฐ ๋ก๋ฉ์ ์ค์ํ์ง ์์ ๋ฆฌ์์ค์ ๋ก๋ฉ์ ํ์ํ ๋๊น์ง ์ง์ฐ์์ผ ์ด๊ธฐ ํ์ด์ง ๋ก๋ ์๊ฐ์ ๊ฐ์ ํฉ๋๋ค.
- ์๋น์ค ์์ปค: ์๋น์ค ์์ปค๋ ๋ฐฑ๊ทธ๋ผ์ด๋์์ ์คํ๋๋ ์๋ฐ์คํฌ๋ฆฝํธ ํ์ผ๋ก, ๋คํธ์ํฌ ์์ฒญ์ ๊ฐ๋ก์ฑ ์คํ๋ผ์ธ ์บ์ฑ ๋ฐ ํธ์ ์๋ฆผ์ ํ์ฑํํ ์ ์์ต๋๋ค.
๊ฒฐ๋ก
ํ๋ก ํธ์๋ ์ฑ๋ฅ API์ Resource Observer๋ ์น์ฌ์ดํธ ์ฑ๋ฅ์ ๋ชจ๋ํฐ๋งํ๊ณ ์ต์ ํํ๋ ๋ฐ ๋งค์ฐ ๊ท์คํ ๋๊ตฌ๋ฅผ ์ ๊ณตํฉ๋๋ค. ๋ฆฌ์์ค๊ฐ ์ด๋ป๊ฒ ๋ก๋๋๊ณ ์ฒ๋ฆฌ๋๋์ง ์ดํดํจ์ผ๋ก์จ ๊ฐ๋ฐ์๋ ๋ณ๋ชฉ ํ์์ ์๋ณํ๊ณ , ๋ฆฌ์์ค ์ ๋ฌ์ ์ต์ ํํ๋ฉฐ, ์ฐ์ํ ์ฌ์ฉ์ ๊ฒฝํ์ ์ ๊ณตํ ์ ์์ต๋๋ค. ์ด๋ฌํ ๊ธฐ์ ๊ณผ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ์์ฉํ๋ ๊ฒ์ ์ค๋๋ ์ฑ๋ฅ ์ค์ฌ์ ์ธ๊ณ์์ ๋น ๋ฅด๊ณ , ๋งค๋ ฅ์ ์ด๋ฉฐ, ์ฑ๊ณต์ ์ธ ์น์ฌ์ดํธ๋ฅผ ๋ง๋๋ ๋ฐ ํ์์ ์ ๋๋ค. ์ง์์ ์ธ ๋ชจ๋ํฐ๋ง๊ณผ ์ต์ ํ๋ ์์น๋ ์ฅ์น์ ๊ด๊ณ์์ด ๊ธ์ ์ ์ธ ์ฌ์ฉ์ ๊ฒฝํ์ ๋ณด์ฅํ๊ณ ์์ ๋๊ฐ๋ ๋ฐ ํต์ฌ์ ๋๋ค.
์ต์ ์ ๊ฒฐ๊ณผ๋ฅผ ์ป์ผ๋ ค๋ฉด ์ด๋ฌํ ์ ๋ต์ ํน์ ๋์ ๊ณ ๊ฐ๊ณผ ์ง๋ฆฌ์ ๋งฅ๋ฝ์ ๋ง๊ฒ ์กฐ์ ํ๋ ๊ฒ์ ์์ง ๋ง์ญ์์ค. ๊ธฐ์ ์ ์ ๋ฌธ ์ง์๊ณผ ๊ธ๋ก๋ฒ ๋์์ค์ ๋ํ ์ดํด๋ฅผ ๊ฒฐํฉํจ์ผ๋ก์จ ๋ชจ๋ ์ฌ๋, ๋ชจ๋ ๊ณณ์์ ์ ์๋ํ๋ ์น์ฌ์ดํธ๋ฅผ ๊ตฌ์ถํ ์ ์์ต๋๋ค.